#pragma once
#include <grpcpp/grpcpp.h>
#include "DataExchange.grpc.pb.h"
#include "app.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;

using DataExchange::StringReply;
using DataExchange::StringRequest;
using DataExchange::StringReverse;
using grpc::ServerCompletionQueue;
using grpc::ServerAsyncResponseWriter;


class AbstractHandler {
public:
    AbstractHandler(DataExchange::DataQuery::AsyncService* service, ServerCompletionQueue* cq);
    virtual void run() =0;
protected:
    DataExchange::DataQuery::AsyncService* service_;
    ServerCompletionQueue* cq_;
    ServerContext ctx_;

    enum class HandlerStatus  { CREATE, PROCESS, FINISH };
    HandlerStatus status_;
};
// Server Implementation


template<typename REQUEST,typename RESPONSE>
struct MethodCallData {
public:
    MethodCallData():responder(&ctx){};
   
    REQUEST request;
    RESPONSE reply;
    ServerAsyncResponseWriter<RESPONSE> responder;
    std::function<void(void*)> process_cb,finish_cb;

  //  DataExchange::DataQuery::AsyncService* service_;
   // ServerCompletionQueue* cq_;
    ServerContext ctx;

    enum class HandlerStatus { CREATE, PROCESS, FINISH };
    HandlerStatus status;

};

class ListContracts :public AbstractHandler {
private:
    DataExchange::ListRequest request_;
    DataExchange::ContractsResponse reply_;
    ServerAsyncResponseWriter<DataExchange::ContractsResponse> responder_;
public:
    ListContracts(DataExchange::DataQuery::AsyncService* service, ServerCompletionQueue* cq);
    // Inherited  via AbstractHandler
    void run() override;

};
class ListCollections :public AbstractHandler {
private:
    DataExchange::ListRequest request_;
    DataExchange::CollectionsResponse reply_;
    ServerAsyncResponseWriter<DataExchange::CollectionsResponse> responder_;
public:
    ListCollections(DataExchange::DataQuery::AsyncService* service, ServerCompletionQueue* cq);
    // Inherited  via AbstractHandler
    void run() override;

};


class DataServer {
private:
    enum class HandlerStatus {CREATE,  PROCESS, FINISH };
    std::unique_ptr<ServerCompletionQueue> m_cq;
    DataExchange::DataQuery::AsyncService m_service;
    std::unique_ptr<Server> m_server;


    void initContractsResponse();
    void initFactorsResponse();
    void initStrategiesResponse();
    void initCollectionsResponse();
    void initCollectionDetail();
public:
    ~DataServer();
    void run();
    void handleRpc();
};






